﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using iLangl.Model;
using iLangl.LanguageWire.LanguageWireAPI;
using System.IO;
using System.Data;
using LW.DB;
using System.Data.SqlClient;
using System.Collections;
using System.Configuration;

namespace iLangl.LanguageWire.DAL.LanguageWireDAL.RealStorage
{
	public class ProjectDAL : BaseStorageLWAPI, IProjectDAL
	{
		public void CreateProject(ProjectLW project, IDbTransaction trans)
		{
			CreateAssignmentRequest createAssignmentRequest = null;
			IList<int> jobs = new List<int>();
			foreach (Translation translation in project.Instance.Translations)
			{
				if (!String.IsNullOrEmpty(translation.TPIdentity))
				{
					continue; // Translation already ordered
				}

				StartSession();
				createAssignmentRequest = new CreateAssignmentRequest();
				SubscribeRequest(createAssignmentRequest);

				//Upload Content
				ContentEntity sourceContent = translation.SourceContent;
				uploadContent(sourceContent);

				//Create Job
				createAssignmentRequest.APICustomerID = LWStorageConfiguration.Instance.APICustomerID;

				createAssignmentRequest.Description = project.Instance.Description;
				createAssignmentRequest.PrimaryWorkAreaId = int.Parse(project.Instance.WorkArea.Id);
				createAssignmentRequest.LanguageSource = int.Parse(translation.LanguagePair.SourceLanguage.LanguageId);
				createAssignmentRequest.LanguageTarget = int.Parse(translation.LanguagePair.TargetLanguage.LanguageId);
				
				createAssignmentRequest.Comment = string.Format("Comment = {0}", translation.Comment);
				createAssignmentRequest.RequiredDeliveryTime = DateTime.Now.AddDays(3);
				
				createAssignmentRequest.ReferenceNumber = translation.Id;
				createAssignmentRequest.CompanyId = int.Parse(project.GetProjectCompany().TPIdentity);

				CreateAssignmentResponse response = service.CreateAssignment(createAssignmentRequest);
				LogResponse(response);
				translation.TPIdentity = response.AssignmentId.ToString();

				iLangl.LanguageWire.DAL.iLanglDAL.DALFacade.Instance.TranslationDAL.UpdateTranslation(translation, trans);

				if (response.FileIds.Length > 0)
					iLangl.LanguageWire.DAL.iLanglDAL.DALFacade.Instance.ProjectDAL.UpdateContentReference(sourceContent.Id, response.FileIds[0], trans);

				jobs.Add(response.AssignmentId);
				

				StopSession();
			}

			if (jobs.Count > 0)
			{
				StartSession();
				//Create Project
				CreateProjectRequest createProjectRequest = new CreateProjectRequest();
				SubscribeRequest(createProjectRequest);
				createProjectRequest.Name = project.Instance.Name;
				createProjectRequest.Description = project.Instance.Description;
				createProjectRequest.Jobs = jobs.ToArray();

				CreateProjectResponse cpr = service.CreateProject(createProjectRequest);
				LogResponse(cpr);

				project.Instance.TPIdentity = cpr.ProjectID.ToString();
				iLangl.LanguageWire.DAL.iLanglDAL.DALFacade.Instance.ProjectDAL.UpdateProjectReference(project.Instance.Id, cpr.ProjectID, trans);
			}

			StopSession();
		}


		private void uploadContent(ContentEntity content)
		{
			UploadFileRequest uploadrequest = new UploadFileRequest();
			SubscribeRequest(uploadrequest);

			string filename = Path.GetFileNameWithoutExtension(content.Name);
			uploadrequest.Filename = String.Format("{0}.xml", filename);
			const int chanksize = 10;

			UploadFileResponse uploadresponse = null;
				byte[] buffer = new byte[chanksize];
				byte[] buffer1 = new byte[chanksize];
			
			byte[] data = System.Text.Encoding.UTF8.GetBytes(content.Content);

			using(MemoryStream ms = new MemoryStream(data))
			{
				while (ms.Position < (ms.Length - chanksize))
					{
						ms.Read(buffer, 0, chanksize);

						uploadrequest.FileData = buffer;
						uploadresponse = service.UploadFile(uploadrequest);
						LogResponse(uploadresponse);
					}

					buffer = new byte[ms.Length - ms.Position];
					ms.Read(buffer, 0, buffer.Length);

					uploadrequest.FileData = buffer;
					uploadresponse = service.UploadFile(uploadrequest);
					LogResponse(uploadresponse);
			}
		}


		public JobInfo GetJobInfo(int jobId)
		{
			DBProvider dbProvider = new DBProvider();
			JobInfo result = null;

			SqlParameter[] parameters = new SqlParameter[]
				{
					new SqlParameter("@JobId", jobId),
				};

			String sqlCommand =
@"select JobID, FSJobID,Status, AdminContactID, SubTypeID from CustomerJobs
where
JobID = @JobId";


			using (SqlDataReader reader = dbProvider.ExecuteReader(sqlCommand, CommandType.Text, parameters))
			{
				if (reader.Read())
				{
					result = new JobInfo();
					result.JobId = (Int32)reader["JobID"];
					result.ParentJobId = (Int32)reader["FSJobID"];
					result.Status = (Int32)reader["Status"];
					result.ResponsiblePerson = (Int32)reader["AdminContactID"];
					result.JobType = (Int32)reader["SubTypeID"];
				}

			}

			if (result != null)
			{
				result.Jobs = GetChildrenJobs(jobId);
			}
			return result;
		}

		public  Int32[] GetChildrenJobs(int ParentJobId)
		{
			ArrayList result = new ArrayList();

			DBProvider dbProvider = new DBProvider();
			using (SqlDataReader reader = dbProvider.ExecuteReader(
			   String.Format("select JobID from CustomerJobs where FSJobID = {0}", ParentJobId), CommandType.Text))
			{
				while (reader.Read())
				{
					result.Add((Int32)reader["JobId"]);
				}
			}

			return (Int32[])result.ToArray(typeof(Int32));
		}


		public ContentEntity[] DownloadSourceContent(Translation translation)
		{
			GetTranslatedDataRequest getTranslatedDataRequest = new GetTranslatedDataRequest();
			SubscribeRequest(getTranslatedDataRequest);
			getTranslatedDataRequest.OrderId = int.Parse(translation.TPIdentity);

			GetTranslatedDataResponse getTranslatedDataResponse = service.GetTranslatedData(getTranslatedDataRequest);
			LogResponse(getTranslatedDataResponse);

			List<ContentEntity> result = new List<ContentEntity>();

			if (getTranslatedDataResponse.Files != null)
			{
				foreach (iLangl.LanguageWire.LanguageWireAPI.File f in getTranslatedDataResponse.Files)
				{
					DownloadFileRequest dfrequest = new DownloadFileRequest();
					DownloadFileResponse dfs = null;
					SubscribeRequest(dfrequest);
					dfrequest.FileId = f.FileId;
					dfrequest.Downloaded = 0;

					using (MemoryStream ms = new MemoryStream())
					{
						dfs = service.DownloadFile(dfrequest);
						dfrequest.Downloaded = dfs.Downloaded;
						ms.Write(dfs.Data, 0, dfs.Data.Length);

						while (ms.Position < dfs.FileSize)
						{
							dfs = service.DownloadFile(dfrequest);
							dfrequest.Downloaded = dfs.Downloaded;
							ms.Write(dfs.Data, 0, dfs.Data.Length);
						}


						ContentEntity ce = new ContentEntity();
						ce.Id = Guid.NewGuid().ToString();
						ce.TPIdentity = f.FileGuid.ToString();
						ce.Language = translation.LanguagePair.TargetLanguage;
						ce.Name = f.FileName;

						ms.Position = 0;
						StreamReader sr = new StreamReader(ms);
						ce.Content = sr.ReadToEnd();

						result.Add(ce);

					}
				}
			}

			return result.ToArray();
		}

		#region IProjectDAL Members


		/// <summary>
		/// Return progress from AT if document exists for current assignment
		/// </summary>
		/// <param name="jobID"></param>
		/// <returns></returns>
		public int GetProgress(JobInfo job)
		{
			DBProvider dbProvider = new DBProvider(ConfigurationManager.ConnectionStrings["AgitoTranslate"].ConnectionString);

			string sqlCommand = @"utf_sp_GetProgressByJobId";

			SqlParameter[] parameters = new SqlParameter[]
				{
					new SqlParameter("@JobId", job.JobId),
				};

			int translationProgress = 0;
			int proofreadingProgress = 0;
			int validationProgress = 0;

			using (SqlDataReader reader = dbProvider.ExecuteReader(sqlCommand, CommandType.StoredProcedure, parameters))
			{
				if (reader.Read())
				{
					translationProgress = (Int32)reader["TranslationProgress"];
					proofreadingProgress = (Int32)reader["ValidationProgress"];
					validationProgress = (Int32)reader["ProofreadingProgress"];
				}
			}



			switch (job.JobType)
			{
				case 1:
					return translationProgress;
				case 2:
				case 17:
				case 7:
				case 4:
				case 22:
					return proofreadingProgress;
				case 5:
				case 16:
				case 8:
					return validationProgress;
				default:
					return translationProgress;
			}
		
		}

		#endregion

	}
}
